import { ethers } from "ethers";
import "dotenv/config";

function requireEnv(name) {
  const v = process.env[name];
  if (!v || !v.trim()) throw new Error(`缺少环境变量: ${name}`);
  return v.trim();
}

async function main() {
  console.log("=== Sepolia 转账示例（EIP-1559）===");

  const RPC_URL = requireEnv("RPC_URL");
  const PRIVATE_KEY = requireEnv("PRIVATE_KEY");
  const TO_ADDRESS = requireEnv("TO_ADDRESS");
  const AMOUNT_ETH = process.env["AMOUNT_ETH"]?.trim() || "0.001";
  const MAX_PRIORITY_GWEI = process.env["MAX_PRIORITY_GWEI"]?.trim();
  const MAX_FEE_GWEI = process.env["MAX_FEE_GWEI"]?.trim();

  if (!ethers.isAddress(TO_ADDRESS)) {
    throw new Error(`收款地址无效: ${TO_ADDRESS}`);
  }

  const provider = new ethers.JsonRpcProvider(RPC_URL);
  const network = await provider.getNetwork();
  const chainId = Number(network.chainId);
  console.log(`连接网络: ${network.name || "unknown"} (chainId=${chainId})`);
  if (chainId !== 11155111) {
    throw new Error("警告: 当前非 Sepolia 链。请确认 RPC 配置是否正确。");
  }

  const wallet = new ethers.Wallet(PRIVATE_KEY, provider);
  console.log(`付款地址: ${wallet.address}`);

  const senderBalanceWei = await provider.getBalance(wallet.address);
  console.log(`付款地址余额: ${ethers.formatEther(senderBalanceWei)} ETH`);

  const toBalanceBeforeWei = await provider.getBalance(TO_ADDRESS);
  console.log(`收款地址初始余额: ${ethers.formatEther(toBalanceBeforeWei)} ETH`);

  const valueWei = ethers.parseEther(AMOUNT_ETH);

  // 估算 gas
  const gasLimit = await wallet.estimateGas({ to: TO_ADDRESS, value: valueWei });
  console.log(`估算 gasLimit: ${gasLimit.toString()}`);

  // 获取费用建议（EIP-1559）
  const feeData = await provider.getFeeData();
  let maxPriorityFeePerGas = feeData.maxPriorityFeePerGas ?? ethers.parseUnits("2", "gwei");
  let maxFeePerGas = feeData.maxFeePerGas ?? ethers.parseUnits("30", "gwei");

  if (MAX_PRIORITY_GWEI) {
    maxPriorityFeePerGas = ethers.parseUnits(MAX_PRIORITY_GWEI, "gwei");
  }
  if (MAX_FEE_GWEI) {
    maxFeePerGas = ethers.parseUnits(MAX_FEE_GWEI, "gwei");
  }

  // 构造交易
  const nonce = await provider.getTransactionCount(wallet.address);
  const tx = {
    to: TO_ADDRESS,
    value: valueWei,
    nonce,
    chainId,
    gasLimit,
    maxPriorityFeePerGas,
    maxFeePerGas,
  };

  console.log("发送交易...");
  const sent = await wallet.sendTransaction(tx);
  console.log(`交易已提交，hash: ${sent.hash}`);
  console.log(`Etherscan: https://sepolia.etherscan.io/tx/${sent.hash}`);

  console.log("等待上链确认...");
  const receipt = await sent.wait();
  console.log(`已打包区块: ${receipt.blockNumber}`);
  console.log(`交易状态: ${receipt.status === 1 ? "成功" : "失败"}`);

  const toBalanceAfterWei = await provider.getBalance(TO_ADDRESS);
  const delta = toBalanceAfterWei - toBalanceBeforeWei;
  console.log(`收款地址余额变更: +${ethers.formatEther(delta)} ETH`);

  if (receipt.status !== 1) {
    throw new Error("交易未成功写入链，请检查 gas 费与余额。");
  }

  console.log("完成。你已在 Sepolia 完成一次程序化转账！");
}

main().catch((err) => {
  console.error("执行失败:", err.message);
  process.exit(1);
});